package com.sora.transport.netty.server;

import com.sora.factory.SingletonFactory;
import com.sora.handler.RequestHandler;
import com.sora.entity.RpcRequest;
import com.sora.entity.RpcResponse;
import com.sora.registry.ServiceRegistry;
import com.sora.factory.ThreadPoolFactory;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.util.ReferenceCountUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.concurrent.ExecutorService;

/**
 * @Classname: NettyServerHandler
 * @Description:
 * @Author: Stonffe
 * @Date: 2023/5/1 14:42
 */
public class NettyServerHandler extends SimpleChannelInboundHandler<RpcRequest> {
    private static final Logger logger = LoggerFactory.getLogger(NettyServerHandler.class);
    private final RequestHandler requestHandler;
    private static ServiceRegistry serviceRegistry;
    private static final String THEAD_NAME_PREFIX = "netty-server-handler";
    private final ExecutorService threadPool;
    public NettyServerHandler() {
        this.requestHandler = SingletonFactory.getInstance(RequestHandler.class);
        this.threadPool = ThreadPoolFactory.createDefaultThreadPool(THEAD_NAME_PREFIX);
    }
    @Override
    protected void channelRead0(ChannelHandlerContext ctx, RpcRequest rpcRequest) throws Exception {
        threadPool.execute(()->{
            try {
                logger.info("服务器接收到请求：{}", rpcRequest);
                Object result = requestHandler.handle(rpcRequest);
                if (ctx.channel().isActive() && ctx.channel().isWritable()) {
                    ctx.writeAndFlush(RpcResponse.success(rpcRequest.getRequestId(), result));
                } else {
                    logger.error("通道不可写");
                }
            } finally {
                ReferenceCountUtil.release(rpcRequest);
            }
        });
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        logger.error("处理过程调用时有错误发生：");
        cause.printStackTrace();
        ctx.close();
    }
}
